<!DOCTYPE html>
<html>
<body>
  <div id="root"></div>
  <div id="root1"></div>
  <div id="root2"></div>
</body>
<script src="./reactv18/babel.min.js"></script>
<script src="./reactv18/react.development.js"></script>
<script src="./reactv18/react-dom.development.js"></script>
<!-- 1. 引入类型限制js, 在react15版本以前，这个集成在react库当中，之后独立开来 -->
<script src="./reactv18/prop-types.js"></script>

<script type="text/babel">
  // 本例子可以证明diffing算法的更新，span在更新，而input不会吧输入的内容刷掉
  
  /**经典面试题
  1）. react/vue中的key有什么作用？，内部原理是什么？
  2）. 为什么遍历列表时，key最好不要用index

  1. 虚拟Dom中的key的作用
    a. 简单的说，key是虚拟Dom对象的标识， 在更新显示时key起着及其重要的作用
    b. 详细的说，当状态中的数据发生变化时，react会根据新数据生成的新的虚拟Dom，
    随后React进行新虚拟Dom和老的虚拟Dom的diff比较，比较规则如下：
      * 旧虚拟Dom中找到了新虚拟Dom相同的key, 若虚拟Dom中内容没有变，直接使用之前的真实Dom
      若虚拟Dom中内容变了，则生成新的真实DOM，替换之前的真实Dom。
      * 旧虚拟Dom中未找到新虚拟Dom相同的key
      根据数据创建新的真实Dom，随后渲染到页面

  2. 用index做为key可能会引发问题
    a. 若对数据进行 逆序添加、逆序删除等破坏顺序操作，会产生没有必要的真实Dom更新，界面效果随看不出来，但效率低
    b. 如果机构中还包含输入类的Dom 会产生错误Dom更新，界面有问题
    c. 注意，如果不存在数据逆序添加，逆序删除等破坏性操作，仅用于暄软列表展示，使用index作为Key是没有问题的

  3. 开发中如何选择key
    * 最好使用每条数据的唯一标识作为Key，比如id、手机号、身份证、学号唯一值
    * 若果确定只是简单的展示数据，用Index也可以
*/


  class Person extends React.Component{
    state = {
      persons: [
        {id: 1, name: "小张", age: 18},
        {id: 2, name: "小王", age: 19},
        {id: 3, name: "小李", age: 20},
      ]
    }

    add = ()=>{
      const {persons} = this.state
      const p = {id: persons.lenght + 1, name: "小黄", age: 23}
      this.setState({persons: [p, ...persons]})
    }

    render(){
      return (
        <div>
          <h2>使用index作为Key</h2>
          <button onClick={this.add}>添加一个人</button>
          <ul>
          {
            this.state.persons.map((personObj, index)=>{
              return (
                <li key={index}>{personObj.name}--{personObj.age} <input type="text" /></li>
              )
            })
          }
          </ul>
          <hr/>
          <h2>使用Id作为key-高效率</h2>
          <button onClick={this.add}>添加一个人</button>
          <ul>
          {
            this.state.persons.map((personObj, index)=>{
              return (
                <li key={personObj.id}>{personObj.name}--{personObj.age} <input type="text" /></li>
              )
            })
          }
          </ul>

        </div>
        
      )
    }
  }
  const container = document.getElementById('root')
  const root = ReactDOM.createRoot(container)
  root.render(<Person />)
</script>
</html>
